import config from "./config.js"
import { promisifyChooseImage, promisifyChooseVideo, promisifyShowModal } from "./util.js"

const MAX_VIDEO_SIZE = 10;					// 视频大小10MB
const MAX_VIDEO_DURATION = 60;			// 视频最大时长
const MAX_VIDEO_WIDTH = 1080;				// 视频最大帧宽
const MAX_VIDEO_HEIGHT = 1920;			// 视频最大帧高
const MAX_IMAGE_COUNT = 9;					// 图片张数
const MAX_IMAGE_SIZE = 1;						// 图像大小1MB

/**
 * 基础文件上传器
 * @param {*} param0 
 */
export const baseUploader = ({
	url = config.baseApi + config.uploadApi, 
	filePath, 
	name = 'file', 
	formData = {}, 
	timeout = 60000,
	progressCb,
	abortCb
}) => {
	return new Promise((resolve, reject) => {
		if (!filePath) {
			reject(new Error('文件资源路径不能为空'))
		}
		// 成功
		const success = function (response) {
			const { statusCode, data } = response;
			if (statusCode >= 200 && statusCode < 300) {
				const dataObj = JSON.parse(data)
				if (dataObj.code !== 0) {
					reject(new Error(dataObj.message || 'error'))
				} else {
					resolve(dataObj)
				}
			} else {
				reject(new Error(statusCode))
			}
		}
		
		// 失败
		const fail = function (error) {
			reject(new Error(error.errMsg || 'error upload!!!'))
		}
		
		// 执行上传
		const uploadConfig = {
			url,
			filePath,
			name,
			formData,
			timeout,
			success,
			fail,
		}
		const uploadTask = wx.uploadFile(uploadConfig)

		// 监听上传进度
		uploadTask.onProgressUpdate(event => {
			typeof progressCb === 'function' && progressCb(event)
		})

		// 终止上传
		typeof abortCb === 'function' && abortCb(() => uploadTask.abort())
	})
}

/**
 * 多图上传
 * @param {*} maxCount 最多上传数量
 * @param {*} curCount 已经上传数量
 * @param {*} maxSize  最大文件大小
 * @param {*} sizeType 所选图片尺寸
 * @param {*} success  上传成功回调 每个文件都会回调
 * @param {*} successAll 上传成功回调 所有文件完成才会回调
 */
export const onMultiUploadImage = async ({
	maxCount = MAX_IMAGE_COUNT,
	curCount = 0,
	maxSize = MAX_IMAGE_SIZE,
	sizeType = ['original', 'compressed'],
	success,
	successAll,
}) => {
	// 选择图片
	const chooseImageOptions = {
		count: maxCount - curCount,
		sizeType,
		sourceType: ['album']
	}
	const { tempFiles } = await promisifyChooseImage(chooseImageOptions)
	
	// 大小过滤 获取合法的图片数组
	const fileList = tempFiles.filter(item => (item.size/1024/1024) <= maxSize)
	if (!fileList.length) {
		return uni.showToast({ title: `请上传${maxSize}M以内图片`, icon: 'none' })
	}
	
	// 过滤提示
	if (fileList.length < tempFiles.length) {
		const { cancel } = await promisifyShowModal({
			title: '提示',
			content: `您共选择了${tempFiles.length}张图片, 其中${tempFiles.length - fileList.length}张图片大小超出${maxSize}M限制，是否继续`,
			cancelColor: '#07c160',
			confirmColor: '#ee0a24',
		})
		if (cancel) return
	}
	
	// 上传完成列表
	const imageList = []
	// 显示当前上传个数
	const showLoadingCount = fileList.length > 1
	// 循环上传
	fileList.map(async (item, index) => {
		// 最后一张显示成功提示
		const lastFile, showToast = index == (fileList.length - 1)
		const loadingTitle = showLoadingCount ? `正在上传第${index+1}张` : undefined
		const data = await onUpload(item.path, loadingTitle, showToast)
		// 每上传一次 回调一次
		typeof success === 'function' && success(data)
		imageList.push(data)
		// 所有都完成上传 回调全部文件
		if (lastFile) {
			typeof successAll === 'function' && successAll(imageList)
		}
	})
}

/**
 * 单图上传
 * @param {*} maxSize  		最大文件大小
 * @param {*} showToast 	显示成功提示
 * @param {*} sizeType  	所选图片的尺寸
 * @param {*} sourceType  选择图片的来源
 */
export const onSingleUploadImage = async ({
	maxSize = MAX_IMAGE_SIZE,
	showToast = false,
	sizeType = ['original', 'compressed'],
	sourceType = ['album', 'camera'],
}) => {
	// 选择图片
	const { tempFiles } = await promisifyChooseImage({
		count: 1,
		sizeType,
		sourceType
	})
	// 验证图片大小
	const { path, size } = tempFiles
	if (size > maxSize) {
		return uni.showToast({ title: `请上传${maxSize}M以内图片`, icon: 'none' })
	}
	// 上传服务器
	const data = await onUpload(path, undefined, showToast)
	return data
}

/**
 * 执行上传
 * @param {*} path 上传资源临时路径
 * @param {*} showToast 是否显示上传成功提示
 */
export const onUpload = async (path, loadingTitle = '正在上传', showToast = true) => {
	try {
		uni.showLoading({ title: loadingTitle, mask: true })
		const data = await baseUploader({ filePath: path })

		if (showToast) {
			uni.hideLoading()
			uni.showToast({ title: '上传成功' })
		}
		return data
	} catch (error) {
		uni.hideLoading()
		uni.showToast({ title: error.message, icon: 'none' })
		throw error
	}
}

/**
 * 上传视频
 * @param {array} sourceType		视频选择的来源 
 * @param {boolean} compressed	是否压缩所选择的视频文件
 * @param {string} camera				默认拉起的是前置或者后置摄像头
 * @param {number} maxDuration	拍摄视频最长拍摄时间，单位秒
 * @param {number} maxSize			最大文件大小 单位MB
 * @param {number} maxWidth			最大视频的宽度
 * @param {number} maxHeigth		最大视频的高度
 * @param {function} callback		上传成功回调
 */
export const onUploadVideo = async ({
	sourceType = ['album', 'camera'],
	compressed = true,
	camera = 'back',
	maxDuration = MAX_VIDEO_DURATION,
	maxSize = MAX_VIDEO_SIZE,
	maxWidth = MAX_VIDEO_WIDTH,
	maxHeigth = MAX_VIDEO_HEIGHT,
}) => {
	// 选择视频
	const res = await promisifyChooseVideo({
		sourceType,
		compressed,
		maxDuration, 
		camera
	})
	const { duration, size, width, height, tempFilePath } = res

	if (Math.floor(duration) > maxDuration) {
		uni.showToast({ title: `请上传${maxDuration}秒以内视频`, icon: 'none' })
	} else if (size/1024/1024 > maxSize) {
		uni.showToast({ title: `请上传${maxSize}M以内视频`, icon: 'none' })
	} else if (width > maxWidth) {
		uni.showToast({ title: `请上传帧宽度${maxWidth}以内视频`, icon: 'none' })
	} else if (height > maxHeigth) {
		uni.showToast({ title: `请上传帧高度${maxHeigth}以内视频`, icon: 'none' })
	} else {
		try {
			const data = await baseUploader({
				filePath: tempFilePath,
				progressCb: progress => {
					uni.showLoading({ title: `正在上传${progress.progress}%`, mask: true })
				}
			})
			uni.hideLoading()
			uni.showToast({ title: '上传成功' })
			return data
		} catch (error) {
			uni.hideLoading()
			uni.showToast({ title: error.message, icon: 'none' })
			throw error
		}
	}
}